/* global document, Fuse */

const searchContainer = document.querySelector('#global-search-container');
const searchInput = document.querySelector('#global-search-input');
const searchCloseButton = document.querySelector('#search-close-button');
const resultBox = document.querySelector('#search-result-container');
const globalSearchButton = document.querySelector('.global-search-button');

function showResultText(text) {
    if (resultBox) {
        resultBox.innerHTML = `<div class="search-result-message">${text}</div>`;
    }
}

function hideSearch() {
    if (searchContainer) {
        searchContainer.style.display = 'none';
        document.body.style.overflow = '';
    }
}

function showSearch() {
    if (searchContainer) {
        searchContainer.style.display = 'flex';
        document.body.style.overflow = 'hidden';
    }
    if (searchInput) {
        searchInput.focus();
    }
}

async function fetchAllData() {
    try {
        const response = await fetch('data/search.json');
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const data = await response.json();
        return data.list || data;
    } catch (error) {
        console.error('Failed to fetch search data:', error);
        throw error;
    }
}

function buildSearchResult(result) {
    let output = '';
    const removeHTMLTagsRegExp = /(<([^>]+)>)/ig;

    for (const res of result) {
        const { title = '', description = '', type = '', link = '' } = res.item;

        const _title = title.replace(removeHTMLTagsRegExp, "");
        const _description = description.replace(removeHTMLTagsRegExp, "");
        const _link = link.replace(/^<a href="/, '').replace(/">.*$/, '');

        // 获取类型图标
        const typeIcon = getTypeIcon(type);

        output += `
        <a href="${_link}" class="search-result-item">
            <div class="search-result-item-header">
                <span class="search-result-type-icon">${typeIcon}</span>
                <div class="search-result-item-title">${_title}</div>
            </div>
            <div class="search-result-item-description">${_description || 'No description available.'}</div>
        </a>
        `;
    }

    return output;
}

function getTypeIcon(type) {
    const icons = {
        'class': '🏛️',
        'function': '⚡',
        'method': '⚡',
        'namespace': '📦',
        'module': '📦',
        'constant': '🔒',
        'member': '🔧',
        'typedef': '📝',
        'event': '⚡',
        'page': '📄'
    };
    return icons[type] || '📄';
}

function getSearchResult(list, keys, searchKey) {
    const defaultOptions = {
        shouldSort: true,
        threshold: 0.6,
        location: 0,
        distance: 1000,
        maxPatternLength: 64,
        minMatchCharLength: 1,
        keys: keys,
        // 添加更多搜索选项
        includeScore: true,
        includeMatches: true
    };

    const options = { ...defaultOptions };
    const searchIndex = Fuse.createIndex(options.keys, list);
    const fuse = new Fuse(list, options, searchIndex);
    const result = fuse.search(searchKey);

    return result.length > 20 ? result.slice(0, 20) : result;
}

function debounce(func, wait, immediate) {
    let timeout;
    return function () {
        const args = arguments;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            timeout = null;
            if (!immediate) {
                func.apply(this, args);
            }
        }, wait);
        if (immediate && !timeout) {
            func.apply(this, args);
        }
    };
}

let searchData;

async function search(event) {
    const value = event.target.value;
    const keys = ['title', 'description'];

    if (!resultBox) {
        console.error('Search result container not found');
        return;
    }

    if (!value) {
        showResultText('Type anything to view search result');
        return;
    }

    if (!searchData) {
        showResultText('Loading...');
        try {
            searchData = await fetchAllData();
        } catch (e) {
            console.error('Failed to load search data:', e);
            showResultText('Failed to load search data. Please try again later.');
            return;
        }
    }

    const result = getSearchResult(searchData, keys, value);

    if (!result.length) {
        showResultText('No result found! Try some different combination.');
        return;
    }

    resultBox.innerHTML = buildSearchResult(result);
}

function initSearch() {
    const debouncedSearch = debounce(search, 200);

    // 搜索按钮事件
    if (globalSearchButton) {
        globalSearchButton.addEventListener('click', showSearch);
    }

    // 关闭按钮事件
    if (searchCloseButton) {
        searchCloseButton.addEventListener('click', hideSearch);
    }

    // 容器点击事件（点击背景关闭）
    if (searchContainer) {
        searchContainer.addEventListener('click', function (event) {
            if (event.target === searchContainer) {
                hideSearch();
            }
        });
    }

    // 搜索输入事件
    if (searchInput) {
        searchInput.addEventListener('input', debouncedSearch);

        // 预加载搜索数据
        searchInput.addEventListener('focus', async function () {
            if (!searchData) {
                try {
                    searchData = await fetchAllData();
                } catch (e) {
                    console.error('Failed to preload search data:', e);
                }
            }
        });
    }

    // 键盘快捷键
    document.addEventListener('keydown', function (event) {
        // Ctrl/Cmd + K 打开搜索
        if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
            event.preventDefault();
            showSearch();
        }

        // Escape 关闭搜索
        if (event.key === 'Escape' && searchContainer && searchContainer.style.display !== 'none') {
            hideSearch();
        }
    });
}

// 初始化
document.addEventListener('DOMContentLoaded', initSearch);